using Corpus.Application.Const;
using Corpus.Application.Service.Dto;
using Corpus.Core.Service;
using Furion.DatabaseAccessor;
using Furion.FriendlyException;
using JiebaNet.Segmenter;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
using SqlSugar;
using System.IO;
using System.Linq;

namespace Corpus.Application.Service;

[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 200)]
[AllowAnonymous]
public class YuLiaoKService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<YuLiaoK> _yuLiaoKRep;
    private readonly SqlSugarRepository<FenCiJL> _fenCiJLRep;
    private readonly SqlSugarRepository<Config> _configRep;
    private readonly ISqlSugarClient _db;

    public YuLiaoKService(
        SqlSugarRepository<YuLiaoK> yuLiaoKRep,
        SqlSugarRepository<FenCiJL> fenCiJLRep,
        SqlSugarRepository<Config> configRep,
        ISqlSugarClient db
        )
    {
        _yuLiaoKRep = yuLiaoKRep;
        _fenCiJLRep = fenCiJLRep;
        _configRep = configRep;
        _db = db;
    }
    /// <summary>
    /// 图片上传
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [HttpPost("/YuLiaoK/Upload")]
    public async Task<FileOutPut> Upload(IFormFile file)
    {
        var dto = new FileOutPut();
        if (Path.GetExtension(file.FileName).ToLower() != ".gif")
        {
            dto.code = -1;
            dto.msg = "仅支持gif的图片文件。";
        }
        else
        {
            var path = Path.Combine(App.WebHostEnvironment.WebRootPath, "Upload", DateTime.Now.ToString("yyyy"), DateTime.Now.ToString("yyyyMM"));
            if (!Directory.Exists(path)) { Directory.CreateDirectory(path); }
            var filename = $"{Guid.NewGuid()}.gif";
            var filepath = Path.Combine(path, filename);
            dto.src = $"/Upload/{DateTime.Now.ToString("yyyy")}/{DateTime.Now.ToString("yyyyMM")}/{filename}";
            dto.filename = file.FileName.ToLower().Replace(".gif", "");
            //
            using (var fileStream = new FileStream(filepath, FileMode.Create))
            {
                await file.CopyToAsync(fileStream);
            }
        }

        return dto;
    }
    /// <summary>
    /// 获取分页列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet("/YuLiaoK/page")]
    public async Task<SqlSugarPagedList<YuLiaoK>> GetPage([FromQuery] YuLiaoKPageInput input)
    {
        return await _yuLiaoKRep.AsQueryable()
                .Where(c => c.state == 1)
                .WhereIF(!string.IsNullOrWhiteSpace(input.word), u => u.word.Contains(input.word))
                .WhereIF(!string.IsNullOrWhiteSpace(input.author), u => u.author.Contains(input.author))
                .OrderBy(u => u.LastDate, OrderByType.Desc)
                .ToPagedListAsync(input.Page, input.PageSize);
    }
    /// <summary>
    /// 待审核分页列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet("/YuLiaoK/waitpage")]
    public async Task<SqlSugarPagedList<YuLiaoK>> GetWaitPage([FromQuery] YuLiaoKPageInput input)
    {
        return await _yuLiaoKRep.AsQueryable()
                .Where(c => c.state == 0)
                .WhereIF(!string.IsNullOrWhiteSpace(input.word), c => c.word.Contains(input.word))
                .WhereIF(!string.IsNullOrWhiteSpace(input.author), c => c.author.Contains(input.author))
                .OrderBy(u => u.LastDate, OrderByType.Desc)
                .ToPagedListAsync(input.Page, input.PageSize);
    }
    /// <summary>
    /// 待完善分页列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet("/YuLiaoK/daiwanspage")]
    public async Task<SqlSugarPagedList<FenCiJL>> GetDaiWanSPage([FromQuery] YuLiaoKPageInput input)
    {
        var sql = "select * from ylk_fencijl A where NOT EXISTS(select 1 from ylk_yuliaok B where A.word=B.word)";
        return await _db.SqlQueryable<FenCiJL>(sql)
                .WhereIF(!string.IsNullOrWhiteSpace(input.word), c => c.word.Contains(input.word))
                .ToPagedListAsync(input.Page, input.PageSize);
    }

    /// <summary>
    /// 增加
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost("/YuLiaoK/add")]
    public async Task Add(YuLiaoKAddInput input)
    {
        var en = input.Adapt<YuLiaoK>();
        await _yuLiaoKRep.InsertAsync(en);
    }

    /// <summary>
    /// 批量增加
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost("/YuLiaoK/batchadd")]
    public async Task BatchAdd(YuLiaoKBatchAddInput input)
    {
        var lst = new List<YuLiaoK>();
        foreach (var item in input.lst)
        {
            lst.Add(new YuLiaoK { word = item.word, author = input.author, gif = item.gif, state = 1 });
        }
        await _db.Insertable(lst).ExecuteCommandAsync();
    }

    /// <summary>
    /// 更新
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost("/YuLiaoK/update")]
    public async Task Update(YuLiaoKUpdateInput input)
    {
        var en = input.Adapt<YuLiaoK>();
        en.state = 1;
        await _yuLiaoKRep.InsertAsync(en);
    }
    /// <summary>
    /// 批量审核
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost("/YuLiaoK/check")]
    public async Task Update(YuLiaoKCheckInput input)
    {
        await _db.Updateable<YuLiaoK>()
                    .SetColumns(c => c.state == input.state)
                    .Where(c => input.lstid.Contains(c.Id))
                    .ExecuteCommandAsync();
    }
    /// <summary>
    /// 批量删除语料库
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost("/YuLiaoK/batchDelete")]
    [UnitOfWork]
    public async Task batchDelete(YuLiaoKDeleteInput input)
    {
        await _db.Deleteable<YuLiaoK>().Where(c => input.lstid.Contains(c.Id)).ExecuteCommandAsync();
    }
    /// <summary>
    /// 批量删除分词记录
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost("/FenCiJL/batchDelete")]
    [UnitOfWork]
    public async Task batchFenCiJLDelete(YuLiaoKDeleteInput input)
    {
        await _db.Deleteable<FenCiJL>().Where(c => input.lstid.Contains(c.Id)).ExecuteCommandAsync();
    }
    /// <summary>
    /// 分词并返回匹配记录
    /// </summary>
    [HttpPost("/YuLiaoK/FenCi")]
    public List<YuLiaoKOutPut> FenCi(YuLiaoKInput input)
    {
        //获取忽略词
        var lstInterpunction = GetSingleConfig("interpunction");
        //所有正式语料库
        var allyuliaok = _yuLiaoKRep.AsQueryable().Where(c => c.state == 1).ToList();

        var lstjl = new List<FenCiJL>();
        var lst = new List<YuLiaoKOutPut>();
        var segmenter = new JiebaSegmenter();
        foreach (var item in segmenter.Cut(input.txt))
        {
            var word = item.Trim();
            if(string.IsNullOrWhiteSpace(word)) continue;
            //
            var dto = allyuliaok.FirstOrDefault(c => c.word == word);
            if (dto == null)
                lst.Add(new YuLiaoKOutPut { word = word, color = "red" });
            else
                lst.Add(new YuLiaoKOutPut
                {
                    color = "green",
                    word = dto.word,                   
                    gif = dto.gif,
                    author = dto.author,
                    time = dto.LastDate.ToString("yyyy-MM-dd")
                });
            //不记录忽略词
            if (!lstInterpunction.Contains(item)) lstjl.Add(new FenCiJL { word = item });
        };
        if (lstjl.Count > 0) _db.Insertable(lstjl).ExecuteCommand();

        return lst;
    }

    #region "配置相关"
    /// <summary>
    /// 获取所有配置
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    [HttpGet("/YuLiaoK/getSingleConfig")]
    public List<string> GetSingleConfig([FromQuery] string key)
    {
        var en = _configRep.AsQueryable().Where(c => c.key == key).Single();
        if (en != null)
            return en.value.Split('|').ToList();
        else
            return new List<string>();
    }
    /// <summary>
    /// 获取所有配置
    /// </summary>
    /// <returns></returns>
    [HttpGet("/YuLiaoK/getConfig")]
    public async Task<List<Config>> GetConfig()
    {
        return await _configRep.AsQueryable().ToListAsync();
    }
    /// <summary>
    /// 保存配置
    /// </summary>
    /// <param name="lst"></param>
    [HttpPost("/YuLiaoK/saveConfig")]
    public void SaveConfig(List<ConfigAddInput> lst)
    {
        foreach (var item in lst)
        {
            var count = _db.Updateable<Config>().SetColumns(c => c.value == item.value)
                           .Where(c => c.key == item.key).ExecuteCommand();
            //未找到更新则插入
            if (count == 0)
            {
                _configRep.Insert(new Config { key = item.key, value = item.value });
            }
        }
    }
    #endregion

    /// <summary>
    /// 词云（热词前100）
    /// </summary>
    /// <returns></returns>
    [HttpGet("/YuLiaoK/getWordCloud")]
    public dynamic GetWordCloud()
    {
        var sql = "SELECT word name,count(1) value from ylk_fencijl GROUP BY word ORDER BY count(1) desc LIMIT 0,100";
        return _db.Ado.SqlQuery<dynamic>(sql).ToList();
    }
}